package com.sc.nft.admin.controller;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import com.sc.nft.admin.request.*;
import com.sc.nft.admin.vo.EcologyReleaseRuleAndmultipleVO;
import com.sc.nft.annotation.SysMemberLogin;
import com.sc.nft.dao.StaticDataDao;
import com.sc.nft.entity.vo.AdminSalvageEventsPageVO;
import com.sc.nft.entity.vo.UserPointsDetailsStatisticsVO;
import com.sc.nft.entity.vo.ecology.*;
import com.sc.nft.entity.vo.merchantPledgeTask.AdminEcologyPointsDataVO;
import com.sc.nft.enums.EcologyIncomeTypeEnum;
import com.sc.nft.enums.EcologyPointsEnum;
import com.sc.nft.enums.IncomeTypeEnum;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.UserEcologyPointsService;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/admin/ecology/points")
@Api(tags = "后台用户燃料管理")
public class AdminUserEcologyPointsDetailController {

    private final UserEcologyPointsService userEcologyPointsService;
    private final Redisson redisson;
    private final StaticDataDao staticDataDao;

    //EcologyPointsUserPage
    @PostMapping(value = "/getUserPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "分页获取用户燃料列表", notes = "分页获取用户燃料列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<AdminEcologyPointsUserPageVO> getUserPage(@Valid @RequestBody AdminEcologyPointsUserPageRequest request) {
        return PageResult.success(userEcologyPointsService.getUserPage(request.getUserTel(),request.getPageNo(),request.getPageSize()));
    }

    @PostMapping(value = "/editUserPoints", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "编辑用户生态燃料", notes = "编辑用户生态燃料", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result editUserPoints(@Valid @RequestBody AdminEditUserPointsRequest request) {
        RLock lock = redisson.getLock(RedisKeyEnum.EDIT_USER_POINTS_LOCK.getKey() + request.getId());
        try {
            boolean res = lock.tryLock(3, TimeUnit.SECONDS);
            if (res) {
                userEcologyPointsService.editUserPoints(request.getId(),request.getIsAdd(),request.getAmount(),request.getRemark());
            }else {
                return Result.fail(ErrorCode.LATER_TRY);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            throw new GlobalRunTimeException("系统超时");
        } finally {
            lock.unlock();
        }
        return Result.success();
    }

    @PostMapping(value = "/getUserDetailsPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "分页获取用户燃料记录明细列表", notes = "分页获取用户燃料记录明细列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<AdminEcologyPointsUserPageDetailsVO> getUserDetailsPage(@Valid @RequestBody AdminEcologyPointsUserPageDetailsRequest request) {
        return PageResult.success(userEcologyPointsService.getUserDetailsPage(request.getUserId(),request.getType(),request.getStartTime(),request.getEndTime(),request.getPageNo(),request.getPageSize()));
    }


    @PostMapping(value = "/getUserPointsType", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取用户燃料变更类型", notes = "获取用户燃料变更类型", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<List<Map>> getUserPointsType() {
        return PageResult.success(EcologyPointsEnum.getDescriptionAndName());
    }

    @PostMapping(value = "/getEcologyReleaseRuleAndmultiple", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取释放规则和倍数", notes = "获取释放规则和倍数", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<EcologyReleaseRuleAndmultipleVO> getEcologyReleaseRuleAndmultiple() {
        String ecologyReleaseRule = staticDataDao.getByType("ecology_release_rule").getValue();
        String ecologyReleaseMultiple = staticDataDao.getByType("ecology_release_multiple").getValue();

        EcologyReleaseRuleAndmultipleVO ecologyReleaseRuleAndmultipleVO = new EcologyReleaseRuleAndmultipleVO();
        ecologyReleaseRuleAndmultipleVO.setEcologyReleaseRule(ecologyReleaseRule);
        ecologyReleaseRuleAndmultipleVO.setEcologyReleaseMultiple(ecologyReleaseMultiple);
        return Result.success(ecologyReleaseRuleAndmultipleVO);
    }

    @PostMapping(value = "/editEcologyReleaseRule", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "修改释放规则", notes = "获取释放规则和倍数", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result editEcologyReleaseRule(@Valid @RequestBody EditEcologyRelease request) {
        Assert.isTrue(staticDataDao.updateStaticData("ecology_release_rule",request.getValue()),()->new GlobalRunTimeException("修改失败"));
        return Result.success();
    }

    @PostMapping(value = "/editEcologyReleaseMultiple", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "修改可释放倍数", notes = "修改可释放倍数", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result editEcologyReleaseMultiple(@Valid @RequestBody EditEcologyRelease request) {
        BigDecimal ecologyReleaseMultiple = Convert.toBigDecimal(request.getValue());
        Assert.isFalse(NumberUtil.isGreaterOrEqual(BigDecimal.ZERO,ecologyReleaseMultiple),()-> new GlobalRunTimeException("数值范围不正确"));

        BigDecimal bigDecimal = Convert.toBigDecimal(request.getValue()).setScale(2, BigDecimal.ROUND_DOWN);
        Assert.isTrue(NumberUtil.isGreater(bigDecimal,BigDecimal.ZERO),()-> new GlobalRunTimeException("数值范围不正确"));
        String ecologyReleaseMultipleString = bigDecimal.stripTrailingZeros().toPlainString();
        Assert.isTrue(staticDataDao.updateStaticData("ecology_release_multiple",ecologyReleaseMultipleString),()->new GlobalRunTimeException("修改失败"));
        return Result.success();
    }


    @PostMapping(value = "/userPointsDetailsStatistics", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "用户燃料明细统计", notes = "用户燃料明细统计", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<UserPointsDetailsStatisticsVO> userPointsDetailsStatistics(@Valid @RequestBody AdminUserTelRequest request) {
        return Result.success(userEcologyPointsService.userPointsDetailsStatistics(request.getUserTel()));
    }


    @PostMapping(value = "/quotaLog", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "额度记录", notes = "额度记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<AdminQuotaLogVO> quotaLog(@Valid @RequestBody QuotaLogRequest request) {
        return PageResult.success(userEcologyPointsService.quotaLog(request.getUserId(),request.getDaoName(),request.getCollectionName(),request.getStartTime(),request.getEndTime(),request.getPageNo(),request.getPageSize()));
    }

    @PostMapping(value = "/getIncomeTypeList", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取收益类型", notes = "获取收益类型", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<Map> getIncomeTypeList() {
        return Result.success(EcologyIncomeTypeEnum.getAll());
    }

    @PostMapping(value = "/expiredRecords", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "失效记录", notes = "失效记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<AdminExpiredRecordsVO> expiredRecords(@Valid @RequestBody ExpiredRecordsRequest request) {
        return PageResult.success(userEcologyPointsService.expiredRecords(request.getUserId(),request.getIncomeType(),request.getStartTime(),request.getEndTime(),request.getPageNo(),request.getPageSize()));
    }

    @PostMapping(value = "/getEcologyPointsData", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取平台统计数据", notes = "获取平台统计数据", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<AdminEcologyPointsDataVO> getEcologyPointsData() {
        return Result.success(userEcologyPointsService.getEcologyPointsData());
    }



    @PostMapping(value = "/userEcologyUsableAmountUpperLimitDetailPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "可释放额度记录", notes = "可释放额度记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<AdminuserEcologyUsableAmountUpperLimitDetailPageVO> userEcologyUsableAmountUpperLimitDetailPage(@Valid @RequestBody AdminUserEcologyUsableAmountUpperLimitDetailPageRequest request) {
        return PageResult.success(userEcologyPointsService.userEcologyUsableAmountUpperLimitDetailPage(request.getUserId(),request.getStartTime(),request.getEndTime(),request.getPageNo(),request.getPageSize()));
    }



    @PostMapping(value = "/initUsableAmountLimit", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "初始化用户燃料上限额度", notes = "初始化用户燃料上限额度", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result initUsableAmountLimit() {
        userEcologyPointsService.initUsableAmountLimit();
        return Result.success();
    }
}
